#!/usr/bin/python

from rule import Rule

class Rule_manager:
  def __init__(self):
    self.flexRules = []
    self.subjRules = []
    self.baseRules = []
    self.loadRulesFrom()

  def loadRulesFrom(self, subjFileName = "subjectRules.nlp", flexFileName = "rules.nlp", baseFileName = "baseForms.nlp"):
    subjFile = open(subjFileName, "r")
    flexFile = open(flexFileName, "r")
    baseFile = open(baseFileName, "r")
    
    subjFileCont = subjFile.read()
    flexFileCont = flexFile.read()
    baseFileCont = baseFile.read()
    
    subjFile.close()
    flexFile.close()
    baseFile.close()
    
    self.subjRules = self.__parseContent(subjFileCont)
    self.flexRules = self.__parseContent(flexFileCont)
    self.baseRules = self.__parseContent(baseFileCont)

  def __parseContent(self, fileContent):
    #parsing rule input file HAXIOR MODE ON
    keyValList = map(lambda x: x.split(';'), fileContent.split('\n'))
    rules = [len(x) == 2 and [x[0].split("&"), x[1]] for x in keyValList]
 
    resultTab = []
    for it in rules:
      if it: #in case where there were any empty lines in file
	      value = it[1].strip()
	      attr = {} #init attributes dict
	      for jt in it[0]:
	        tab = jt.split("=")
	        attr[tab[0].strip()] = self.__parseValue( tab[1].strip() )
	      #creating new rule obj
	      resultTab.append(Rule(attr, value))
	  # HAXIOR MODE OFF
    return resultTab

  def __parseValue(self, value):
    if value.find("|") > -1:
      return value.split("|")
    elif value.find("-") > -1:
      val = value.split("-")
      return [str(x) for x in xrange(int(val[0]),int(val[1])+1)]
    else:
      return [value]

  def getSubjectFor(self, attributes):
    return self.__getResultFor(attributes, self.subjRules)
  
  def getFlexFor(self, attributes):
    return self.__getResultFor(attributes, self.flexRules)

  def getBaseFor(self, attributes):
    return self.__getResultFor(attributes, self.baseRules)

  def __getResultFor(self, attributes, listOfRules):
    for rule in listOfRules:
      if rule.getDistance(attributes) == 0:
	      return rule.result
    return None


def assertion(current, expected):
  if current != expected:
    if current is None:
      current = "None"

    if expected is None:
      expected = "None"

    print "Current: " + current + " but expected: " + expected
    raise 

# ------------------------
if __name__ == "__main__":
  rM = Rule_manager()

  try:
    current = rM.getSubjectFor({'base':'4' , 'fleks':'num'})
    expected = "czter"
    assertion(current, expected)

    current = rM.getBaseFor({'base':'2'})
    expected = "dwa"
    assertion(current, expected)

    current = rM.getFlexFor({'base':'1' , 'fleks':'num', 'liczba':'sg', 'przypadek':'dat', 'rodzaj':'f'})
    expected = "nej"
    assertion(current, expected)

    current = rM.getFlexFor({'base':'2' , 'fleks':'num', 'liczba':'pl', 'przypadek':'voc', 'rodzaj':'n'})
    expected = "a"
    assertion(current, expected)

    current = rM.getFlexFor({'base':'6' , 'fleks':'num', 'liczba':'pl', 'przypadek':'gen', 'rodzaj':'f'})
    expected = "ciu"
    assertion(current, expected)
  except:
    #for rule in rM.flexRules:
    #  print str(rule.result) + " for " + str(rule.attributes)
    print 'Error'

  pass

